#include "hmi_module.h"
#include "temp_module.h"
#include "adc_module.h"
#include "flow_module.h"
#include "water_module.h"
#include "valve_module.h"
#include "pid_module.h"
#include "alarm_module.h"
#include "log_module.h"
#include <string.h>

static rt_thread_t hmi_thread = RT_NULL;
static screen_page_t current_page = SCREEN_MAIN;
static uint32_t last_update_time = 0;
static rt_mq_t hmi_event_queue = RT_NULL;

/* 趋势数据缓冲区 */
static struct {
    float temperature[100];
    float flow_rate[100];
    float pressure[100];
    uint8_t index;
    uint8_t count;
} trend_data;

/* 更新主页面显示数据 */
static rt_err_t update_main_page_data(void)
{
    rt_err_t result;
    char buffer[32];
    
    /* 更新温度显示 */
    for (int i = 0; i < 4; i++) {
        float temp = temp_get_temperature(i);
        result = dc_screen_write_variable(MAIN_TEMP1_VALUE + i, temp);
        if (result != RT_OK) {
            LOG_W("Failed to update temperature %d display\n", i);
        }
    }
    
    /* 更新流量显示 */
    for (int i = 0; i < 2; i++) {
        float flow = flow_get_flow_rate(i);
        result = dc_screen_write_variable(MAIN_FLOW1_VALUE + i, flow);
        if (result != RT_OK) {
            LOG_W("Failed to update flow %d display\n", i);
        }
    }
    
    /* 更新压力显示 */
    float pressure = adc_get_engineering_value(0); /* 假设第一个通道是压力 */
    result = dc_screen_write_variable(MAIN_PRESSURE_VALUE, pressure);
    
    /* 更新水质显示 */
    float water_quality = water_get_quality_value(0);
    result = dc_screen_write_variable(MAIN_WATER_QUALITY, water_quality);
    
    /* 更新阀门位置 */
    float valve_pos = valve_get_position_percent();
    result = dc_screen_write_variable(MAIN_VALVE_POSITION, valve_pos);
    
    /* 更新PID输出 */
    float pid_output = pid_get_output(PID_HEATER);
    result = dc_screen_write_variable(MAIN_PID_OUTPUT, pid_output);
    
    /* 更新系统状态 */
    const char *status = pid_get_auto_control() ? "自动模式" : "手动模式";
    result = dc_screen_write_string(MAIN_SYSTEM_STATUS, status);
    
    return RT_OK;
}

/* 更新设置页面数据 */
static rt_err_t update_settings_page_data(void)
{
    rt_err_t result;
    
    /* 更新温度设定值 */
    float setpoint = pid_get_setpoint(PID_HEATER);
    result = dc_screen_write_variable(SET_TEMP_SETPOINT, setpoint);
    
    /* 更新PID参数 */
    pid_config_t *pid_cfg = pid_get_config();
    if (pid_cfg != RT_NULL) {
        result = dc_screen_write_variable(SET_PID_KP, pid_cfg->controllers[PID_HEATER].kp);
        result = dc_screen_write_variable(SET_PID_KI, pid_cfg->controllers[PID_HEATER].ki);
        result = dc_screen_write_variable(SET_PID_KD, pid_cfg->controllers[PID_HEATER].kd);
    }
    
    /* 更新报警限值 */
    alarm_config_t *alarm_cfg = alarm_get_config();
    if (alarm_cfg != RT_NULL && alarm_cfg->alarms[0].enabled) {
        uint16_t limits = ((uint16_t)alarm_cfg->alarms[0].high_limit << 8) | 
                         (uint16_t)alarm_cfg->alarms[0].low_limit;
        result = dc_screen_write_register(SET_ALARM_LIMITS, limits);
    }
    
    return RT_OK;
}

/* 更新报警页面数据 */
static rt_err_t update_alarms_page_data(void)
{
    rt_err_t result;
    char alarm_text[64];
    uint8_t alarm_count = 0;
    
    alarm_config_t *alarm_cfg = alarm_get_config();
    if (alarm_cfg == RT_NULL) {
        return RT_ERR_PARAM;
    }
    
    /* 更新报警数量 */
    for (int i = 0; i < MAX_ALARMS; i++) {
        if (alarm_cfg->alarms[i].triggered) {
            alarm_count++;
            
            /* 更新报警列表 */
            rt_snprintf(alarm_text, sizeof(alarm_text), "报警%d: 通道%d", i+1, i);
            result = dc_screen_write_string(ALARM_LIST_START + i, alarm_text);
        } else {
            /* 清空未触发的报警显示 */
            dc_screen_write_string(ALARM_LIST_START + i, "");
        }
    }
    
    /* 更新报警计数 */
    result = dc_screen_write_register(ALARM_COUNT, alarm_count);
    
    return RT_OK;
}

/* 更新趋势数据 */
static rt_err_t update_trend_data(void)
{
    /* 采集当前数据点 */
    float current_temp = temp_get_temperature(0);
    float current_flow = flow_get_flow_rate(0);
    float current_pressure = adc_get_engineering_value(0);
    
    /* 添加到趋势缓冲区 */
    trend_data.temperature[trend_data.index] = current_temp;
    trend_data.flow_rate[trend_data.index] = current_flow;
    trend_data.pressure[trend_data.index] = current_pressure;
    
    trend_data.index = (trend_data.index + 1) % 100;
    if (trend_data.count < 100) {
        trend_data.count++;
    }
    
    /* 发送最新数据点到屏幕 */
    // 这里需要根据大彩屏的趋势图控件协议来发送数据
    
    return RT_OK;
}

/* 处理HMI事件 */
static rt_err_t process_hmi_event(hmi_event_t *event)
{
    if (event == RT_NULL) {
        return RT_ERR_PARAM;
    }
    
    switch (event->op_type) {
        case HMI_OP_SET_TEMPERATURE:
            pid_set_setpoint(PID_HEATER, event->float_value);
            log_write(LOG_OPERATION, MODULE_HMI, "设定温度修改", event->float_value);
            break;
            
        case HMI_OP_SET_PID_PARAM:
            {
                float kp = 0, ki = 0, kd = 0;
                /* 根据地址确定是哪个参数 */
                switch (event->address) {
                    case SET_PID_KP:
                        kp = event->float_value;
                        ki = pid_get_config()->controllers[PID_HEATER].ki;
                        kd = pid_get_config()->controllers[PID_HEATER].kd;
                        break;
                    case SET_PID_KI:
                        kp = pid_get_config()->controllers[PID_HEATER].kp;
                        ki = event->float_value;
                        kd = pid_get_config()->controllers[PID_HEATER].kd;
                        break;
                    case SET_PID_KD:
                        kp = pid_get_config()->controllers[PID_HEATER].kp;
                        ki = pid_get_config()->controllers[PID_HEATER].ki;
                        kd = event->float_value;
                        break;
                }
                pid_set_parameters(PID_HEATER, kp, ki, kd, 0, 100);
                log_write(LOG_OPERATION, MODULE_HMI, "PID参数修改", event->float_value);
            }
            break;
            
        case HMI_OP_SET_ALARM_LIMIT:
            {
                float low_limit = (event->value & 0xFF);
                float high_limit = ((event->value >> 8) & 0xFF);
                alarm_set_limits(0, low_limit, high_limit, ALARM_LEVEL_WARNING);
                log_write(LOG_OPERATION, MODULE_HMI, "报警限值修改", high_limit);
            }
            break;
            
        case HMI_OP_CHANGE_MODE:
            pid_set_auto_control(event->value ? RT_TRUE : RT_FALSE);
            log_write(LOG_OPERATION, MODULE_HMI, 
                     event->value ? "切换到自动模式" : "切换到手动模式", 0);
            break;
            
        case HMI_OP_RESET_ALARM:
            for (int i = 0; i < MAX_ALARMS; i++) {
                alarm_get_config()->alarms[i].triggered = RT_FALSE;
            }
            log_write(LOG_OPERATION, MODULE_HMI, "报警复位", 0);
            break;
            
        case HMI_OP_SAVE_CONFIG:
            config_save();
            log_write(LOG_OPERATION, MODULE_HMI, "保存配置", 0);
            break;
            
        default:
            break;
    }
    
    return RT_OK;
}

/* 处理屏幕发送的消息（按钮事件等） */
static void process_screen_message(uint8_t *data, uint8_t len)
{
    hmi_event_t event;
    
    if (data == RT_NULL || len < 3) {
        return;
    }
    
    /* 解析大彩屏发送的指令 */
    uint16_t address = (data[0] << 8) | data[1];
    uint16_t value = (data[2] << 8) | data[3];
    
    /* 根据地址判断操作类型 */
    rt_memset(&event, 0, sizeof(event));
    
    switch (address) {
        case SET_TEMP_SETPOINT:
            event.op_type = HMI_OP_SET_TEMPERATURE;
            event.float_value = value / 10.0f;  /* 假设屏幕发送的值放大了10倍 */
            break;
            
        case SET_PID_KP:
        case SET_PID_KI:
        case SET_PID_KD:
            event.op_type = HMI_OP_SET_PID_PARAM;
            event.address = address;
            event.float_value = value / 1000.0f;  /* 假设屏幕发送的值放大了1000倍 */
            break;
            
        case SET_ALARM_LIMITS:
            event.op_type = HMI_OP_SET_ALARM_LIMIT;
            event.value = value;
            break;
            
        case SET_SYSTEM_MODE:
            event.op_type = HMI_OP_CHANGE_MODE;
            event.value = value;
            break;
            
        default:
            /* 页面切换等特殊指令 */
            if (address >= 0x8000) {
                /* 页面切换指令 */
                current_page = (screen_page_t)(address & 0x0F);
                log_write(LOG_OPERATION, MODULE_HMI, "页面切换", current_page);
            }
            break;
    }
    
    /* 发送事件到HMI线程 */
    if (event.op_type != HMI_OP_NONE) {
        rt_mq_send(hmi_event_queue, &event, sizeof(event));
    }
}

/* 大彩屏接收回调函数（更新版本） */
static rt_err_t screen_rx_callback_enhanced(rt_device_t dev, rt_size_t size)
{
    static uint8_t rx_buffer[DC_SCREEN_BUFFER_SIZE];
    static uint8_t rx_index = 0;
    
    rt_size_t read_len = rt_device_read(dev, 0, rx_buffer + rx_index, size);
    if (read_len > 0) {
        rx_index += read_len;
        
        /* 查找完整的数据帧 */
        for (uint8_t i = 0; i < rx_index - 3; i++) {
            /* 检查帧头 */
            if (rx_buffer[i] == 0xAA && rx_buffer[i+1] == 0x55) {
                uint8_t data_len = rx_buffer[i+3];
                if (i + 4 + data_len <= rx_index) {
                    /* 找到完整帧，处理它 */
                    process_screen_message(&rx_buffer[i+4], data_len);
                    
                    /* 移除已处理的数据 */
                    uint8_t frame_len = 4 + data_len;
                    rt_memmove(rx_buffer, rx_buffer + i + frame_len, rx_index - i - frame_len);
                    rx_index -= (i + frame_len);
                    break;
                }
            }
        }
        
        /* 防止缓冲区溢出 */
        if (rx_index >= DC_SCREEN_BUFFER_SIZE - 10) {
            rx_index = 0;
        }
    }
    
    return RT_OK;
}

rt_err_t hmi_module_init(void)
{
    rt_err_t result;
    
    /* 初始化大彩屏通信 */
    result = dc_screen_init();
    if (result != RT_OK) {
        LOG_E("Failed to initialize DC screen\n");
        return result;
    }
    
    /* 创建HMI事件队列 */
    hmi_event_queue = rt_mq_create("hmi_events", sizeof(hmi_event_t), 10, RT_IPC_FLAG_FIFO);
    if (hmi_event_queue == RT_NULL) {
        LOG_E("Failed to create HMI event queue\n");
        return RT_ERR_MEM;
    }
    
    /* 初始化趋势数据 */
    trend_data.index = 0;
    trend_data.count = 0;
    rt_memset(trend_data.temperature, 0, sizeof(trend_data.temperature));
    rt_memset(trend_data.flow_rate, 0, sizeof(trend_data.flow_rate));
    rt_memset(trend_data.pressure, 0, sizeof(trend_data.pressure));
    
    /* 创建HMI线程 */
    hmi_thread = rt_thread_create("hmi", 
                                 hmi_thread_entry, 
                                 RT_NULL, 
                                 2048, 
                                 8,  /* 较高优先级，确保界面响应 */
                                 20);
    if (hmi_thread == RT_NULL) {
        LOG_E("Failed to create HMI thread\n");
        rt_mq_delete(hmi_event_queue);
        return RT_ERR_MEM;
    }
    
    /* 设置增强版接收回调 */
    rt_device_set_rx_indicate(screen_uart, screen_rx_callback_enhanced);
    
    LOG_I("HMI module initialized successfully\n");
    return RT_OK;
}

void hmi_thread_entry(void *parameter)
{
    rt_uint32_t tick;
    hmi_event_t event;
    
    /* 初始化显示：切换到主页面 */
    dc_screen_change_page(SCREEN_MAIN);
    rt_thread_mdelay(100);
    
    /* 更新初始数据 */
    hmi_update_display_data();
    
    while (1) {
        tick = rt_tick_get();
        
        /* 处理HMI事件 */
        while (rt_mq_recv(hmi_event_queue, &event, sizeof(event), 0) == RT_EOK) {
            process_hmi_event(&event);
        }
        
        /* 定期更新显示数据 */
        if (tick - last_update_time >= HMI_UPDATE_INTERVAL) {
            hmi_update_display_data();
            last_update_time = tick;
        }
        
        /* 更新趋势数据（较慢的更新频率） */
        if (tick % 5000 == 0) {  /* 每5秒更新一次趋势 */
            update_trend_data();
        }
        
        rt_thread_mdelay(100);
    }
}

rt_err_t hmi_update_display_data(void)
{
    switch (current_page) {
        case SCREEN_MAIN:
            return update_main_page_data();
        case SCREEN_SETTINGS:
            return update_settings_page_data();
        case SCREEN_ALARMS:
            return update_alarms_page_data();
        case SCREEN_TRENDS:
            return update_trend_data();
        default:
            return RT_OK;
    }
}

rt_err_t hmi_process_event(hmi_event_t *event)
{
    return process_hmi_event(event);
}

rt_err_t hmi_show_alarm_page(void)
{
    current_page = SCREEN_ALARMS;
    return dc_screen_change_page(SCREEN_ALARMS);
}

rt_err_t hmi_show_main_page(void)
{
    current_page = SCREEN_MAIN;
    return dc_screen_change_page(SCREEN_MAIN);
}

rt_err_t hmi_update_trend_data(void)
{
    return update_trend_data();
}

screen_page_t get_current_screen_page(void)
{
    return current_page;
}